<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus';

import { computed, onBeforeMount, reactive, ref, toRefs } from 'vue';

import { ElArrowRight, ElSearch, FciFolder } from '@vben/icons';

import { StorageManager } from '@vben-core/shared/cache';

import {
  ElBreadcrumb,
  ElBreadcrumbItem,
  ElButton,
  ElCard,
  ElCol,
  ElDialog,
  ElDivider,
  ElForm,
  ElFormItem,
  ElIcon,
  ElInput,
  ElLoading,
  ElMessage,
  ElRow,
  ElScrollbar,
  ElSelect,
  ElTree,
} from 'element-plus';

import { catalogApi, fileApi } from '#/api';

import {
  folderIcon,
  geojsonIcon,
  otherIcon,
  pdfIcon,
  shpIcon,
  tupianIcon,
  zipIcon,
} from '../assets';

const props = defineProps({
  isFileViewerShow: {
    type: Boolean,
    default: false,
  },
  catalogId: {
    default: '',
    type: String,
  },
  dataName: {
    default: '选择文件',
    type: String,
  },
  resourceType: {
    default: 'userData',
    type: String,
  },
  filterArray: {
    default: [
      { label: 'Shapes (*.shp)', value: 'Shapes' },
      { label: 'Grid (*.sgrd *.tif *.tiff)', value: 'Grid' },
      { label: 'All (*.all)', value: 'All' },
    ],
    type: Array<{ label: string; value: string }>,
  },
  fileEvent: {
    default: 'select',
    type: String,
  },
});
const emit = defineEmits([
  'closeFileViewer',
  'confirmSelect',
  'saveFile',
  'confirmModel',
  'saveModel',
]);
const storageManager = new StorageManager({
  prefix: '',
  storageType: 'sessionStorage',
});
interface BreadCrumbCatalog {
  id: number;
  title: string;
  catalogId: string;
}
interface CatalogListData {
  id: string;
  name: string;
  type: string;
  updatedTime: string;
  size: number;
}
const { isFileViewerShow, dataName, catalogId, resourceType, filterArray } =
  toRefs(props);

const closeFileViewer = () => {
  emit('closeFileViewer');
};

const ruleFormRef = ref<FormInstance>();
const rules = reactive<FormRules>({
  name: [{ required: true, message: '文件夹名称不能为空！', trigger: 'blur' }],
});
const Rules = reactive<FormRules>({
  fileName: [
    { required: true, message: '文件名称不能为空！', trigger: 'blur' },
  ],
  type: [{ required: true, message: '文件类型不能为空！', trigger: 'blur' }],
  catalog: [{ required: true, message: '目标目录不能为空！', trigger: 'blur' }],
});
const FormData = reactive({
  fileId: '',
  fileName: '',
  suffix: '',
  catalogId: '',
});
const relatedData = reactive({
  id: '',
  label: '',
  type: '',
  catalogId: '',
});

const searchPlaceholder = ref('在MyData中搜索文件...');
const userId = storageManager.getItem('userId');
const rootCatalog = catalogId?.value as string;
const sceneName = storageManager.getItem('editingScene');
const addNewFolderDialog = ref(false);
const loadingText = ref('loading...');
const currentCatalog = ref('');
const unZipCatalog = ref('');
const fileContentLeftSpan = ref(24);
let clickedNode = null;
const currentKey = ref();
const folderBread = [];
let clickCount = 0;
const realId: any[] = [];
const search = ref('');
const sortMethod = ref(filterArray.value[0].value);

const treeData = ref([]);
const breadcrumbItemData = reactive({
  data: [] as BreadCrumbCatalog[],
});
const breadcrumbItemDataS = reactive({
  data: [] as BreadCrumbCatalog[],
});
const catalogList = reactive({
  data: [] as CatalogListData[],
});
const catalogFileList = reactive({
  data: [] as CatalogListData[],
});
const currentSelectedCard = reactive({
  data: {} as CatalogListData,
});
const viewloading = ref(false);
const formData = reactive({
  data: {
    name: '',
  },
});
const imageSrc = (type: string) => {
  switch (type) {
    case 'folder': {
      return folderIcon;
    }
    case 'geojson': {
      return geojsonIcon;
    }
    case 'gif': {
      return tupianIcon;
    }
    case 'jpg': {
      return tupianIcon;
    }
    case 'pdf': {
      return pdfIcon;
    }
    case 'png': {
      return tupianIcon;
    }
    case 'shp': {
      return shpIcon;
    }
    case 'zip': {
      return zipIcon;
    }
    default: {
      return otherIcon;
    }
  }
};
currentCatalog.value = rootCatalog;
unZipCatalog.value = 'MyData';

// 刷新数据
const flushCatalogList = async () => {
  const catalogId = currentCatalog.value || rootCatalog;

  try {
    const response = await fileApi.getChildrenofcatalog(catalogId);
    catalogList.data = response;
  } catch (error) {
    console.error('Error:', error);
  }
};
const popBreadCrumbItem = (id: number) => {
  if (resourceType.value === 'userData') {
    breadcrumbItemData.data = breadcrumbItemData.data.filter(
      (item) => item.id <= id,
    );
  } else {
    breadcrumbItemDataS.data = breadcrumbItemDataS.data.filter(
      (item) => item.id <= id,
    );
  }
  flushCatalogList();
};
const jumpCatalog = (catalog: BreadCrumbCatalog) => {
  currentCatalog.value = catalog.catalogId;
  unZipCatalog.value = catalog.title;
  popBreadCrumbItem(catalog.id);
  searchPlaceholder.value = `在${catalog.title}中搜索文件...`;
  flushCatalogList();
};

const backCatalog = () => {
  const index = breadcrumbItemData.data.length - 1;
  const indexS = breadcrumbItemDataS.data.length - 1;

  if ((index - 1 === -1 && indexS < 0) || (indexS === 0 && index < 0)) {
    ElMessage({
      type: 'warning',
      message: '已在根目录，无法返回上一层！',
    });
  } else {
    const isUserData = resourceType.value === 'userData';

    // 选择正确的数据源
    const breadcrumbData = isUserData
      ? breadcrumbItemData.data
      : breadcrumbItemDataS.data;
    const indexValue = isUserData ? index : indexS;

    const currentItem = breadcrumbData[indexValue - 1] ?? null;
    const nextItem = breadcrumbData[indexValue] ?? null;

    if (currentItem) {
      currentCatalog.value = currentItem.catalogId;
      unZipCatalog.value = currentItem.title;
      searchPlaceholder.value = `在 ${currentItem.title} 中搜索文件...`;

      // 只有当 nextItem 存在时才调用 popBreadCrumbItem，避免访问 undefined
      if (nextItem) {
        popBreadCrumbItem(nextItem.id);
      }

      jumpCatalog(currentItem);
    } else {
      // 处理 currentItem 为空的情况，防止赋值 undefined
      currentCatalog.value = '';
      unZipCatalog.value = '';
      searchPlaceholder.value = '搜索文件...';
    }
  }
};

const addNewFolder = () => {
  addNewFolderDialog.value = true;
  formData.data.name = '';
};

// 获取目录树
const getFolderTree = async () => {
  flushCatalogList();
  try {
    const response = await fileApi.getFolderTree(rootCatalog);
    treeData.value = response;
  } catch (error) {
    console.error('Error:', error);
  }
};
// 新建文件夹
const createNewFolder = async (formEl: FormInstance | undefined) => {
  if (!formEl) {
    return;
  }
  formEl.validate(async (valid) => {
    if (valid) {
      // 这里是正则表达式，用于检查文件名是否包含非法字符
      const illegalChars = /[∧?*:"<>|]/;
      const folderName = formData.data.name;
      // 检查文件夹名称是否合法
      if (illegalChars.test(folderName)) {
        console.error('文件夹名称包含非法字符');
        ElMessage({
          type: 'warning',
          message: '文件夹名称不能包含特殊字符∧?*:"<>|',
        });
        return false;
      }
      // 如果名称合法，继续执行创建文件夹的操作
      const parentCatalogId = currentCatalog.value || rootCatalog;
      try {
        await fileApi.createNewFolder({
          userId,
          parentCatalogId,
          catalogName: formData.data.name,
        });
        getFolderTree();
        ElMessage({
          type: 'success',
          message: '新建文件夹成功！',
        });
      } catch (error) {
        console.error('error submit!', error);
        return false;
      }
      addNewFolderDialog.value = false;
    } else {
      return false;
    }
  });
};
// 进入文件夹
const enterFolder = async (folder: CatalogListData) => {
  currentCatalog.value = folder.id;
  unZipCatalog.value = folder.name;
  catalogList.data = [] as CatalogListData[];
  currentKey.value = folder.id;
  // console.log(currentKey.value);
  folderBread.push(folder.id);
  if (resourceType.value === 'userData') {
    breadcrumbItemData.data.push({
      id: breadcrumbItemData.data.length,
      title: folder.name,
      catalogId: folder.id,
    });
  } else {
    breadcrumbItemDataS.data.push({
      id: breadcrumbItemDataS.data.length,
      title: folder.name,
      catalogId: folder.id,
    });
  }
  flushCatalogList();
};

// 判断是否为双击事件
const isDoubleClick = () => {
  clickCount++;
  setTimeout(() => {
    clickCount = 0;
  }, 300);
  return clickCount === 2;
};
const clickFileInCatalog = (file: CatalogListData) => {
  // console.log('进入clickFileInCatalog');
  relatedData.id = file.id;
  relatedData.catalogId = currentCatalog.value;
  if (currentCatalog.value === '') {
    relatedData.catalogId = rootCatalog;
  }
  if (dataName.value === '解压' || dataName.value === '选择存储目录') {
    unZipCatalog.value = file.name;
  }
  switch (file.type) {
    case 'folder': {
      relatedData.label = '';
      relatedData.type = '';
      fileContentLeftSpan.value = 24;
      // 判断是否为双击事件
      if (isDoubleClick()) {
        enterFolder(file);
        searchPlaceholder.value = `在${file.name}中搜索文件...`;
      }
      break;
    }
    default: {
      relatedData.label = file.name;
      relatedData.type = file.type;
      FormData.fileName = file.name;
      currentSelectedCard.data = file;
      currentCatalog.value = file.id;
      break;
    }
  }
  // console.log(currentSelectedCard.data);
};

const handleTreeNodeClick = (node: any) => {
  return new Promise((resolve) => {
    clickedNode = node;
    currentKey.value = node.key;
    currentCatalog.value = clickedNode.id;
    relatedData.id = clickedNode.id;
    unZipCatalog.value = clickedNode.label;
    catalogList.data = [] as CatalogListData[];
    searchPlaceholder.value = `在${clickedNode.label}中搜索文件...`;
    catalogApi
      .getCatalogPwd(currentCatalog.value)
      .then((response) => {
        if (response) {
          realId.length = 0;
          breadcrumbItemData.data = [];

          const data = response;
          // data 是返回的目录及父级目录的数组，按顺序拼接
          data.forEach((item: any, index: any) => {
            realId.push(item.catalogId);

            if (resourceType.value === 'userData') {
              // 针对 userData 情况，直接填充 breadcrumbItemData.data
              breadcrumbItemData.data.push({
                id: breadcrumbItemData.data.length,
                title: item.label,
                catalogId: item.catalogId,
              });
            } else {
              // 在非 userData 的情况下，确保只清空一次
              if (index === 0) {
                breadcrumbItemDataS.data = []; // 清空之前的数据，防止重复
                // 添加默认的根节点内容
                breadcrumbItemDataS.data.push({
                  id: 0,
                  title: sceneName.sceneName,
                  // @ts-ignore
                  catalogId: rootCatalog,
                });
              }

              if (index > 1) {
                // 从第 3 层级开始填充 breadcrumbItemDataS.data
                breadcrumbItemDataS.data.push({
                  id: breadcrumbItemDataS.data.length,
                  title: item.label,
                  catalogId: item.catalogId,
                });
              }
            }
          });

          // 更新搜索占位符和当前目录
          currentCatalog.value = data[data.length - 1].catalogId;
          unZipCatalog.value = data[data.length - 1].label;
          searchPlaceholder.value = `在${unZipCatalog.value}中搜索文件...`;

          flushCatalogList(); // 刷新目录列表
          resolve(true);
        } else {
          throw new Error('Failed to fetch catalog list.');
        }
      })
      .catch((error) => {
        console.error(error);
      });
  });
};

const getAll = () => {
  catalogApi.getCatalogTree(rootCatalog).then((response) => {
    catalogFileList.data = response[0].children;
  });
};

// 面包屑长度问题
const dynamicBreadcrumb = computed(() => {
  const maxLength = 18;
  let currentLength = 0;
  const processedBreadcrumb = [];
  if (resourceType.value === 'userData') {
    for (let i = breadcrumbItemData.data.length - 1; i >= 0; i--) {
      const item = breadcrumbItemData.data[i];
      currentLength += item.title.length;
      if (currentLength > maxLength && processedBreadcrumb.length > 0) {
        processedBreadcrumb.unshift({ title: '...', id: null });
        break;
      }
      processedBreadcrumb.unshift(item);
    }
  } else {
    for (let i = breadcrumbItemDataS.data.length - 1; i >= 0; i--) {
      const item = breadcrumbItemDataS.data[i];
      currentLength += item.title.length;
      if (currentLength > maxLength && processedBreadcrumb.length > 0) {
        processedBreadcrumb.unshift({ title: '...', id: null });
        break;
      }
      processedBreadcrumb.unshift(item);
    }
  }
  return processedBreadcrumb;
});
// 搜索&排序
const searchedFiles = computed(() => {
  const searched = catalogList.data.filter(
    (data) =>
      !search.value ||
      data.name.toLowerCase().includes(search.value.toLowerCase()),
  );
  return searched;
});

const sortedFiles = computed(() => {
  let sorted = [...searchedFiles.value];
  switch (sortMethod.value) {
    case 'Excel': {
      sorted = sorted.filter(
        (file) =>
          file.type === 'xlsx' || file.type === 'xls' || file.type === 'csv',
      );
      break;
    }
    case 'Folder': {
      sorted = sorted.filter((file) => file.type === 'folder');
      break;
    }
    case 'Grid': {
      sorted = sorted.filter(
        (file) =>
          file.type === 'tif' ||
          file.type === 'tiff' ||
          file.type === 'sgrd' ||
          file.type === 'folder',
      );
      break;
    }
    case 'Shapes': {
      sorted = sorted.filter(
        (file) => file.type === 'shp' || file.type === 'folder',
      );
      break;
    }
    case 'Table': {
      sorted = sorted.filter(
        (file) => file.type === 'csv' || file.type === 'txt',
      );
      break;
    }
    default: {
      break;
    }
  }
  // console.log('sorted是：', sorted);
  return sorted;
}) as any;

function identifyFileType(filename: string): string {
  // 使用正则表达式匹配文件扩展名
  const match = filename.match(/\.[0-9a-z]+$/i);
  // 如果匹配成功，返回扩展名（去掉点），否则返回空字符串
  return match ? match[0].slice(1) : '';
}

const handleSelectConfirm = () => {
  if (relatedData.id === '') {
    relatedData.catalogId = rootCatalog;
  }
  if (props.fileEvent === 'select' || props.fileEvent === 'unzip') {
    if (resourceType.value === 'modelData') {
      emit('confirmModel', relatedData);
    } else {
      emit('confirmSelect', relatedData);
    }
  } else if (props.fileEvent === 'save') {
    if (resourceType.value === 'modelData') {
      emit('saveModel', relatedData);
    } else {
      relatedData.catalogId = currentCatalog.value;
      if (relatedData.type === '' && sortMethod.value === 'Table') {
        const fileType = identifyFileType(relatedData.label);
        if (fileType === 'txt' || fileType === 'csv') {
          relatedData.type = fileType;
        } else if (fileType === '') {
          relatedData.label += '.txt';
          relatedData.type = 'txt';
        } else {
          ElMessage({
            message: '表格文件暂只支持.txt或.csv',
            type: 'warning',
          });
        }
      }
      emit('saveFile', relatedData);
    }
  }

  emit('closeFileViewer');
};
onBeforeMount(async () => {
  console.warn('resourceType是：', resourceType);
  const loadingInstance = ElLoading.service({
    lock: false,
    text: loadingText.value,
    background: 'rgba(0,0,0,0.1)',
  });
  loadingInstance.setText('loading...');
  getFolderTree();
  getAll();
  try {
    if (resourceType.value === 'userData') {
      breadcrumbItemData.data = [];
      breadcrumbItemData.data.push({
        id: 0,
        title: 'MyData',
        // @ts-ignore
        catalogId: rootCatalog,
      });
    } else if (resourceType.value === 'sceneData') {
      breadcrumbItemDataS.data = [];
      breadcrumbItemDataS.data.push({
        id: 0,
        title: sceneName.sceneName,
        catalogId: rootCatalog,
      });
      searchPlaceholder.value = '在MySceneData中搜索文件...';
    }
    // else if (resourceType.value === 'modelData' && workflowModelCatalogId) {
    //     console.warn("resourceType是：modelData")
    //     breadcrumbItemDataS.data = [];
    //     breadcrumbItemDataS.data.push({
    //         id: 0,
    //         title: "Workflow Model",
    //         //@ts-ignore
    //         catalogId: workflowModelCatalogId,
    //     });
    // }
    currentCatalog.value = '';
    loadingInstance.close();
  } catch (error) {
    console.error('Error when fetching catalog list:', error);
    loadingInstance.close();
  }
});
</script>

<template>
  <div>
    <ElDialog
      draggable
      class="dialog-title"
      v-model="isFileViewerShow"
      width="50vw"
      v-if="isFileViewerShow"
      align-center
      :destroy-on-close="true"
      @close="closeFileViewer"
      :close-on-click-modal="false"
    >
      <template #header>
        <div class="file-text-header">
          <h4 style="color: rgb(48 45 45)">{{ dataName }}</h4>
        </div>
      </template>
      <div style="flex-direction: column">
        <div class="topbox" v-loading="viewloading">
          <div style="display: flex; align-items: center">
            <ElButton style="margin-left: 10px" @click="addNewFolder()">
              新建文件夹
            </ElButton>
            <ElButton style="margin-left: 10px" @click="backCatalog()">
              返回上一层
            </ElButton>
            <div
              style="
                width: 20vw;
                padding: 7px;
                padding-left: 10px;
                margin-left: 20px;
                border: solid 1px rgb(144 143 143 / 74.4%);
                border-radius: 5px;
              "
            >
              <ElBreadcrumb :separator-icon="ElArrowRight">
                <ElBreadcrumbItem
                  v-for="catalog in dynamicBreadcrumb"
                  :key="catalog?.id || 'ellipsis'"
                  replace
                >
                  <a v-if="catalog?.id" @click="jumpCatalog(catalog)">
                    {{ catalog.title }}
                  </a>
                  <span v-else>{{ catalog?.title }}</span>
                </ElBreadcrumbItem>
              </ElBreadcrumb>
            </div>
            <div style="position: absolute; right: 5px; width: 15vw">
              <ElInput
                size="default"
                class="input-with-search"
                :placeholder="searchPlaceholder"
                v-model="search"
                clearable
              >
                <template #append>
                  <ElButton default>
                    <ElIcon color="#409EFC"> <ElSearch /> </ElIcon>
                  </ElButton>
                </template>
              </ElInput>
            </div>
          </div>
        </div>

        <div class="bottombox" v-loading="viewloading">
          <ElScrollbar class="treebox" style="flex: 1">
            <div style="padding: 5px; margin: 5px">
              <span>请选择目录</span>
            </div>
            <ElTree
              default-expand-all
              :data="treeData"
              :current-node-key="currentKey"
              @node-click="handleTreeNodeClick"
            >
              <template #default="{ node, data }">
                <span
                  :class="{ highlight: data.highlight }"
                  :title="node.label"
                >
                  <ElIcon size="15" class="">
                    <FciFolder />
                  </ElIcon>
                  {{ node.label }}
                </span>
              </template>
            </ElTree>
          </ElScrollbar>
          <ElDivider style="height: 99%" direction="vertical" />
          <div
            style="
              display: flex;
              flex: 4;
              flex-direction: column;
              overflow-y: auto;
            "
          >
            <ElScrollbar class="file-FileRow">
              <ElRow :gutter="10" class="file-cardRow1">
                <ElCol
                  v-for="file in sortedFiles"
                  :key="file.id"
                  class="file-cardCol1"
                >
                  <ElCard
                    v-if="dataName === '解压' || dataName === '选择存储目录'"
                    shadow="never"
                    @click="clickFileInCatalog(file)"
                    :title="file.name"
                    :class="{ 'disabled-card': file.type !== 'folder' }"
                  >
                    <img
                      :src="imageSrc(file.type)"
                      style="width: 130px; height: 120px"
                    />
                    <div class="file-cardName1">{{ file.name }}</div>
                  </ElCard>
                  <ElCard
                    v-else
                    shadow="never"
                    @click="clickFileInCatalog(file)"
                    :title="file.name"
                  >
                    <img
                      :src="imageSrc(file.type)"
                      style="width: 130px; height: 120px"
                    />
                    <div class="file-cardName1">{{ file.name }}</div>
                  </ElCard>
                </ElCol>
              </ElRow>

              <template v-if="catalogList.data.length === 0">
                <div class="noData">
                  <span class="noDataFont">暂无数据</span>
                </div>
              </template>
            </ElScrollbar>
            <div class="formRow">
              <ElForm
                style="padding-top: 20px"
                v-if="dataName === '解压' || dataName === '选择存储目录'"
                ref="ruleFormRef"
                :rules="Rules"
                :model="unZipCatalog"
                label-position="right"
              >
                <ElFormItem
                  label="目标目录"
                  size="default"
                  prop="catalog"
                  class="formItem"
                >
                  <ElInput v-model="unZipCatalog" placeholder=" " clearable />
                </ElFormItem>
              </ElForm>
              <ElForm
                v-else
                ref="ruleFormRef"
                :rules="Rules"
                :model="relatedData"
                label-position="right"
              >
                <ElFormItem
                  label="文件名称"
                  size="default"
                  prop="fileName"
                  class="formItem"
                >
                  <ElInput
                    v-model="relatedData.label"
                    placeholder="请输入文件名称"
                    clearable
                  />
                </ElFormItem>
                <ElFormItem
                  label="文件类型"
                  size="default"
                  prop="type"
                  class="formItem"
                >
                  <ElSelect
                    clearable
                    v-model="sortMethod"
                    placeholder=" "
                    size="default"
                  >
                    <el-option
                      v-for="option in filterArray"
                      :key="option.value"
                      :label="option.label"
                      :value="option.value"
                    />
                  </ElSelect>
                </ElFormItem>
              </ElForm>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <ElButton class="mybtn" type="primary" @click="handleSelectConfirm">
            确定
          </ElButton>
          <ElButton class="mybtn" @click="closeFileViewer">取消</ElButton>
        </span>
      </template>
    </ElDialog>
    <!-- 新建文件夹对话框 -->
    <ElDialog
      draggable
      class="dialog-title"
      v-model="addNewFolderDialog"
      width="350px"
      v-if="addNewFolderDialog"
      align-center
      destroy-on-close
    >
      <template #header>
        <div class="file-text-header">
          <h4 style="color: rgb(48 45 45)">新建文件夹</h4>
        </div>
        <ElDivider style="padding: 0; margin: 0" />
      </template>
      <ElForm
        style="padding: 30px"
        :model="formData.data"
        label-width="120px"
        label-position="right"
        ref="ruleFormRef"
        :rules="rules"
      >
        <ElFormItem label="文件夹名称：" size="default" prop="name">
          <ElInput
            v-model.trim="formData.data.name"
            placeholder="请输入文件夹名"
            clearable
          />
        </ElFormItem>
        <ElFormItem>
          <ElDivider
            border-style="hidden"
            style="margin-top: 5px; margin-bottom: 5px"
          />
        </ElFormItem>
      </ElForm>

      <template #footer>
        <span class="dialog-footer">
          <ElButton
            class="mybtn"
            type="primary"
            @click="createNewFolder(ruleFormRef as FormInstance)"
            >创建
          </ElButton>
          <ElButton class="mybtn" @click="addNewFolderDialog = false">
            取消
          </ElButton>
        </span>
      </template>
    </ElDialog>
  </div>
</template>

<style scoped>
/* :deep(.el-dialog) {
  border-radius: 20px;
  height: auto;
} */

.file-text-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  height: 50px;
  padding-top: 10px;
  padding-left: 20px;
  font-size: 25px;
}

.bottombox {
  display: flex;
  height: 53vh;
  padding-top: 10px;
  padding-bottom: 0;
}

:deep(.el-tree) {
  width: 100%;
  overflow: auto;
}

.treebox {
  display: flex;
  flex-direction: column;
  width: 20px;
  overflow: auto;
}

.topbox {
  display: flex;
  align-items: center;
  height: 3vh;
  padding: 10px;
  margin-top: 18px;
}

.file-FileRow {
  display: flex;
  height: 80%;
  max-height: 80%;
  padding: 5px;
  overflow-x: hidden !important;
  border-radius: 5px;
  transition: width 2s;
}

.formRow {
  width: 99%;
  height: auto;
  padding-top: 5px;
}

.file-cardRow1 {
  display: flex;
  flex-wrap: wrap;
}

.file-cardCol1 {
  flex-basis: calc(25%);
  margin-bottom: 5px;
}

.file-cardName1 {
  width: 6vw;
  padding-top: 5px;
  overflow: hidden;
  font-family: '宋体';
  font-size: 1.7vh;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.paddingBox {
  padding: 5px;
}

:deep(.el-select) {
  flex: 1;
}

:deep(.el-card:hover) {
  cursor: pointer;
  background-color: rgb(69 137 240 / 30%);
  border-color: rgb(7 57 196 / 78.1%);
}

.el-dialog {
  border-radius: 20px;
}

.mybtn {
  width: 80px;
  height: 30px;
  font-weight: bolder;
  letter-spacing: 1px;
  border-radius: 3px;
}

/* .el-input__wrapper{
    padding: 0px !important;
    width: 100% !important;
} */
.disabled-card {
  pointer-events: none;
  opacity: 0.5;
}
</style>
